﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace _3D_Processor.Controls
{
    public partial class CalibrationImageViewer : UserControl
    {
        public event SizedChangedEventHandler ImageSizeChanged;

        public CalibrationImageViewer()
        {
            InitializeComponent();
        }

        #region ViewPort

        private int minVtop, minVleft, maxVwidth, maxVheight;

        public Rectangle ViewPort
        {
            get
            {
                //Initialize the rectangle in here
                int presentWidth = LeftPortSlider.Maximum - (minVleft * 2);
                int presentHeight = TopPortSliderInv.Maximum - (minVtop * 2);

                int pLeft = ViewPortLeft - minVleft;
                int pTop = ViewPortTop - minVtop;
                int pWidth = (ViewPortWidth - minVleft) - pLeft;
                int pHeight = (ViewPortHeight - minVtop) - pTop;

                int NewLeft = (int)((float)pLeft * ((float)ImageSize.Width / (float)presentWidth));
                int NewTop = (int)((float)pTop * ((float)ImageSize.Height / (float)presentHeight));
                int NewWidth = (int)((float)pWidth * ((float)ImageSize.Width / (float)presentWidth));
                int NewHeight = (int)((float)pHeight * ((float)ImageSize.Height / (float)presentHeight));
                return new Rectangle(NewLeft, NewTop, NewWidth, NewHeight);
            }
        }

        public int ViewPortTop
        {
            get { return TopPortSliderInv.Maximum- TopPortSliderInv.Value; }
            set
            {
                int vpt=value;
                if (vpt < minVtop) vpt = minVtop;
                if (vpt > (ViewPortHeight - 100)) vpt = ViewPortHeight - 100;
                TopPortSliderInv.Value = TopPortSliderInv.Maximum - vpt;
                UpdateMask();
            }
        }
        
        public int ViewPortLeft
        {
            get { return LeftPortSlider.Value; }
            set
            {
                int vpl = value;
                if (vpl < minVleft) vpl = minVleft;
                if (vpl > (ViewPortWidth - 100)) vpl = ViewPortWidth - 100;
                LeftPortSlider.Value = vpl;
                UpdateMask();
            }
        }
        
        public int ViewPortWidth
        {
            get { return WidthPortSlider.Value; }
            set
            {
                int vpw = value;
                if (vpw > maxVwidth) vpw = maxVwidth;
                if (vpw < (ViewPortLeft + 100)) vpw = (ViewPortLeft + 100);
                WidthPortSlider.Value = vpw;
                UpdateMask();
            }
        }
        
        public int ViewPortHeight
        {
            get { return HeightPortSliderInv.Maximum - HeightPortSliderInv.Value; }
            set
            {
                int vph = value;
                if (vph > maxVheight) vph = maxVheight;
                if (vph < (ViewPortTop + 100)) vph = (ViewPortTop + 100);
                HeightPortSliderInv.Value = HeightPortSliderInv.Maximum - vph;
                UpdateMask();
            }
        }

        private void UpdateMask()
        {
            aBmp = (Bitmap)Bmp.Clone();
            Graphics g = Graphics.FromImage(aBmp);
            Brush brush = new SolidBrush(Color.FromArgb(200, Color.Black));
            if (ViewPortLeft > 0)
            {
                g.FillRectangle(brush, new Rectangle(0, 0, ViewPortLeft, TopPortSliderInv.Maximum));
            }
            if (ViewPortTop > 0)
            {
                g.FillRectangle(brush, new Rectangle(0, 0, LeftPortSlider.Maximum, ViewPortTop));
            }
            if (ViewPortWidth < LeftPortSlider.Maximum)
            {
                g.FillRectangle(brush, new Rectangle(ViewPortWidth, 0, LeftPortSlider.Maximum - ViewPortWidth, TopPortSliderInv.Maximum));
            }
            if (ViewPortHeight < TopPortSliderInv.Maximum)
            {
                g.FillRectangle(brush, new Rectangle(0, ViewPortHeight, LeftPortSlider.Maximum, TopPortSliderInv.Maximum - ViewPortHeight));
            }
            g.Dispose();

            ImageWindow.Image = aBmp;
            ImageWindow.Invalidate();
        }
        #endregion

        #region ShowImage

        Bitmap MainImage;
        private Bitmap Bmp = new Bitmap(400, 300);
        private Bitmap aBmp = new Bitmap(400, 300);
        private Size prevImagesize = new Size(0, 0);
        public Size ImageSize { get; set; }

        public Bitmap WindowImage
        {
            get { return MainImage; }
            set
            {
                if (value == null) { WindowImage = new Bitmap(400, 300); return; }
                ImageSize = value.Size;

                if (ImageSize != prevImagesize)
                {
                    Bmp = new Bitmap(ImageSize.Width, ImageSize.Height);
                    aBmp = new Bitmap(ImageSize.Width, ImageSize.Height);
                }

                int pevWidth = value.Width;
                int pevHeight = value.Height;
                int NewHeight = ImageWindow.Height - 2;
                int NewWidth = (int)(NewHeight * (((float)pevWidth) / ((float)pevHeight)));
                if (NewWidth > ImageWindow.Width-2)
                {
                    NewWidth = ImageWindow.Width - 2;
                    NewHeight = (int)(NewWidth * (((float)pevHeight) / ((float)pevWidth)));
                }
                int NewTop = ((ImageWindow.Height - 2) - NewHeight) / 2;
                int NewLeft = ((ImageWindow.Width - 2) - NewWidth) / 2;

                minVtop = NewTop;
                minVleft = NewLeft;
                maxVheight = (ImageWindow.Height - 2) - NewTop;
                maxVwidth = (ImageWindow.Width-2) - NewLeft;

                Graphics g = Graphics.FromImage(Bmp);
                g.DrawImage(value, new Rectangle(NewLeft, NewTop, NewWidth, NewHeight));
                g.Dispose();
                aBmp = (Bitmap)Bmp.Clone();
                ImageWindow.Image = aBmp;
                UpdateMask();
                if (ImageSize != prevImagesize)
                {
                    ViewPortTop = minVtop;
                    ViewPortLeft = minVleft;
                    ViewPortWidth = maxVwidth;
                    ViewPortHeight = maxVheight;
                }
                prevImagesize = ImageSize;
                MainImage = value;
            }
        }

        #endregion

        private void PortSlider_Scroll(object sender, EventArgs e)
        {
            TrackBar tb = (TrackBar)sender;
            switch (tb.Name)
            {
                case "LeftPortSlider":
                    ViewPortLeft = tb.Value;
                    break;
                case "TopPortSliderInv":
                    ViewPortTop = tb.Maximum - tb.Value;
                    break;
                case "WidthPortSlider":
                    ViewPortWidth = tb.Value;
                    break;
                case "HeightPortSliderInv":
                    ViewPortHeight = tb.Maximum - tb.Value;
                    break;
            }
            Rectangle rect = ViewPort;
            InfoLabel.Text = "x=" + rect.X + " y=" + rect.Y + " w=" + rect.Width + " h=" + rect.Height;
            if (rect.Size == ImageSize)
            {
                InfoLabel.Visible = false;
            }
            else
            {
                InfoLabel.Visible = true;
            }
        }

        private void CalibrationImageViewer_SizeChanged(object sender, EventArgs e)
        {
            int referenceWidth = 484;
            int referenceHeight = 382;

            int WidthDifference = this.Width - referenceWidth;
            int HeightDifference = this.Height - referenceHeight;

            Size HBarsSize = new Size(427, 45);
            Size VBarsSize = new Size(45, 327);
            Size ImageSize = new Size(402, 302);

            Point HeightBarPos = new Point(449, 27);
            Point WidthBarPos = new Point(28, 348);
            Point InfoViewerPos = new Point(41, 326);

            LeftPortSlider.Size = new Size(HBarsSize.Width + WidthDifference, HBarsSize.Height);
            WidthPortSlider.Size = new Size(HBarsSize.Width + WidthDifference, HBarsSize.Height);
            TopPortSliderInv.Size = new Size(VBarsSize.Width, VBarsSize.Height + HeightDifference);
            HeightPortSliderInv.Size = new Size(VBarsSize.Width, VBarsSize.Height + HeightDifference);
            ImageWindow.Size = new Size(ImageSize.Width + WidthDifference, ImageSize.Height + HeightDifference);
            LeftPortSlider.Maximum = ImageWindow.Width - 2;
            WidthPortSlider.Maximum = ImageWindow.Width - 2;
            WidthPortSlider.Value = WidthPortSlider.Maximum;
            TopPortSliderInv.Maximum = ImageWindow.Height - 2;
            TopPortSliderInv.Value = TopPortSliderInv.Maximum;
            HeightPortSliderInv.Maximum = ImageWindow.Height - 2;
            WidthPortSlider.Top = WidthBarPos.Y + HeightDifference;
            HeightPortSliderInv.Left = HeightBarPos.X + WidthDifference;
            InfoLabel.Top = InfoViewerPos.Y + HeightDifference;
            if (ImageSizeChanged != null) ImageSizeChanged(new Size(LeftPortSlider.Maximum, TopPortSliderInv.Maximum));
        }

        public delegate void SizedChangedEventHandler(Size NewSize);

    }
}
